from typing import Optional
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response

from core.user_context import set_user_context_from_payload, clear_user_context
from core.token_manager import decode_token


class UserContextMiddleware(BaseHTTPMiddleware):
    """
    从 Authorization: Bearer <token> 中解析令牌载荷，并在请求生命周期内
    设置用户上下文（ContextVar）。

    注意：该中间件不强制鉴权，仅在存在有效令牌时注入上下文；
    路由仍可通过 Depends(get_current_user) 来进行强制鉴权。
    """

    async def dispatch(self, request: Request, call_next) -> Response:
        token: Optional[str] = None

        # 解析 Authorization 头部
        auth = request.headers.get("Authorization")
        if auth and auth.lower().startswith("bearer "):
            token = auth.split(" ", 1)[1].strip()

        # 注入上下文（忽略解析错误，交由路由依赖处理）
        if token:
            try:
                payload = decode_token(token)
                # 仅在访问令牌时注入上下文
                if payload.get("type") == "access":
                    set_user_context_from_payload(payload)
            except Exception:
                # 静默失败：上下文不设置，让路由依赖报错或走匿名逻辑
                pass

        try:
            response = await call_next(request)
            return response
        finally:
            # 确保请求结束后清理上下文
            clear_user_context()